﻿using HalconDotNet;
using ImageDefine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ImageToolMatch
{
    [Serializable]
    public class ImageToolMatch : ImageToolBase, ImageDefine.IAffine, ImageDefine.IPoint,ImageDefine.ILineTool
    {
        public double[] dMatchX;
        public double[] dMatchY;
        public double[] dMatchA;
        public ToolSetting Setting;
        [NonSerialized]
        public ImageActionerMatch actionerMatch;
        public ImageToolMatch() : base()
        {
            Setting = new ToolSetting();
        }
        public ImageToolMatch(ImageToolBase imageBase) : base(imageBase)
        {
            Setting = new ToolSetting();
        }
        override public void CreateActioner(ImageTask imageTaskIn)
        {
            imageTask = imageTaskIn;
            OutPutResults = new Dictionary<string, string>();
            strTaskName = imageTask.Name;
            actionerMatch = new ImageActionerMatch(this);
        }
        override public void Run(HalconDotNet.HImage hImage, SmartDisplayControl.SmartDisplayControl smartDisplay)
        {
            actionerMatch.Run(hImage, smartDisplay);
           
        }

        public static ImageToolTypeInfo ToolTypeRegister()
        {
            ImageToolTypeInfo imageToolTypeInfo = new ImageToolTypeInfo();
            imageToolTypeInfo.ToolName = "模板匹配工具";
            imageToolTypeInfo.toolType = typeof(ImageToolMatch);
            return imageToolTypeInfo;
        }
        public override Form ShowSettingFrm()
        {
            FormSetting formSetting = new FormSetting(imageTask, this, actionerMatch);
            return formSetting;
        }

        public HXLDCont TransContXLD(HXLDCont xldCoutInput)
        {
            throw new NotImplementedException();
        }

        public HImage TransImage(HImage imageInput)
        {
            throw new NotImplementedException();
        }

        public void TransPoint(double dPx, double dPy, out double dQx, out double dQy)
        {
            throw new NotImplementedException();
        }

        public HXLDPoly TransPolygonXLD(HXLDPoly xldPolyInput)
        {
            throw new NotImplementedException();
        }

        public HRegion TransRegion(HRegion regionInput)
        {
            try
            {
                if (bResultOK)
                {
                    HHomMat2D initHom = new HHomMat2D();
                    initHom.VectorAngleToRigid(Setting.RefRow, Setting.RefCol, 0, dResultY, dResultX , (dResultA * Math.PI) / 180.0);
                    HRegion hRegionR = initHom.AffineTransRegion(regionInput, "nearest_neighbor");
                    return hRegionR;
                }
                else
                {
                    return regionInput;
                }
                //HRegion hRegionT = regionInput.MoveRegion((int)(-sharpModelSetting.RefRow), (int)(-sharpModelSetting.RefCol));



            }
            catch
            {
                return null;
            }
        }

        public HRegion TransRegion(HRegion regionInput, int iIndex)
        {
            try
            {
                if (ImageToolResults[iIndex].Result)
                {
                    HHomMat2D initHom = new HHomMat2D();
                    initHom.VectorAngleToRigid(Setting.RefRow, Setting.RefCol, 0, dMatchY[iIndex], dMatchX[iIndex], dMatchA[iIndex]);
                    HRegion hRegionR = initHom.AffineTransRegion(regionInput, "nearest_neighbor");
                    return hRegionR;
                }
                else
                {
                    return regionInput;
                }
                //HRegion hRegionT = regionInput.MoveRegion((int)(-sharpModelSetting.RefRow), (int)(-sharpModelSetting.RefCol));



            }
            catch
            {
                return null;
            }
        }

        public bool GetPoint(out double dResultX, out double dResultY)
        {
            dResultX = this.ResultX;
            dResultY = this.ResultY;
            return bResultOK;
        }

        public bool GetPoint(out double dResultX, out double dResultY, int iIndex)
        {
            dResultX = this.ImageToolResults[iIndex].ResultX;
            dResultY = this.ImageToolResults[iIndex].ResultY;
            return bResultOK;
        }

        public bool GetLine(out double dRow1, out double dCol1, out double dRow2, out double dCol2)
        {
            dCol1 = ResultX - 100.0 * Math.Cos(AngleToHu(ResultA));
            dRow1 = ResultY + 100.0 * Math.Sin(AngleToHu(ResultA));
            dCol2 = ResultX + 100.0 * Math.Cos(AngleToHu(ResultA));
            dRow2 = ResultY - 100.0 * Math.Sin(AngleToHu(ResultA));
            return bResultOK;
        }

        public bool GetLine(out double dRow1, out double dCol1, out double dRow2, out double dCol2, int iIndex)
        {
            ImageToolResult imageToolResult = ImageToolResults[iIndex];
            dCol1 = imageToolResult.ResultX - 100.0 * Math.Cos(AngleToHu(imageToolResult.ResultA));
            dRow1 = imageToolResult.ResultY + 100.0 * Math.Sin(AngleToHu(imageToolResult.ResultA));
            dCol2 = imageToolResult.ResultX + 100.0 * Math.Cos(AngleToHu(imageToolResult.ResultA));
            dRow2 = imageToolResult.ResultY - 100.0 * Math.Sin(AngleToHu(imageToolResult.ResultA));

            return imageToolResult.Result; ;
        }
        private double AngleToHu(double dAngle)
        {
            return dAngle / 180.0 * Math.PI;
        }

        private double HuToAngle(double dHu)
        {
            return dHu / Math.PI * 180.0;
        }
    }
}
